#include "AIMoveAndAtk.h"

cAIMoveAndAtk::cAIMoveAndAtk(cInfoUnion *info, 
							 cFightScene *FightScene,
							 cInputDevice *InputDevice,
							 cRangeHoney *RangeHoney,
							 cBlockHandler *BlockHandler,
							 cCharacterHandler *CharHandler)
{
	s_InfoUnion = info;
	s_FightScene = FightScene;
	s_InputDevice = InputDevice;
	s_RangeHoney = RangeHoney;
	s_BlockHandler = BlockHandler;
	s_CharHandler = CharHandler;

	s_FocusNPC = NULL;
	s_Players = NULL;
	m_MoveCharacter = NULL;

	m_TimeCounter = 0;

	InitProc();
}

cAIMoveAndAtk::~cAIMoveAndAtk(void)
{
}

void cAIMoveAndAtk::SetFocusNPC(cMyCharacter *npc)
{
	s_FocusNPC = npc;
}

cMyCharacter *cAIMoveAndAtk::GetFocusNPC()
{
	return s_FocusNPC;
}

vector<cMyCharacter*> *cAIMoveAndAtk::GetPlayers()
{
	return s_Players;
}

void cAIMoveAndAtk::SetPlayers(vector<cMyCharacter*> *Players)
{
	s_Players = Players;
}

BOOL cAIMoveAndAtk::Run()
{
	if (m_Proc.empty())
	{
		return AI_DONE;
	}
	switch (m_Proc.front())
	{
	case AP_SelectEnemy:
		
		this->s_SelectedPlayer = s_Players->front();
		m_Proc.pop_front();
			
		break;

	case AP_CountMoveRange:
		
		s_RangeHoney->CleanRangeData(RT_MoveRange);
		CountMoveRange(s_RangeHoney,s_FocusNPC,s_BlockHandler,s_CharHandler);
		//m_MovePosUnion = s_RangeHoney->GetMoveRangePath(s_FocusNPC->GetMatrixPosX()+1,s_FocusNPC->GetMatrixPosY());
		//this->m_MovePosUnion = CountCharMoveUnion(
		//	s_FocusNPC,s_SelectedPlayer->GetMatrixPosX()+1,s_SelectedPlayer->GetMatrixPosY());
		m_Proc.pop_front();

		break;

	case AP_ShowMoveRange:
		
		s_RangeHoney->SetCalledType(RT_MoveRange);
		s_RangeHoney->SetIfShow(true);

		m_Proc.pop_front();

		break;

	case AP_HideMoveRange:

		s_RangeHoney->SetIfShow(false);

		m_Proc.pop_front();
		break;

	case AP_WaitTwoSec:

		if (m_TimeCounter == 0)
		{
			m_TimeCounter = timeGetTime();
		}

		if (timeGetTime() - m_TimeCounter >= 2000)
		{
			m_Proc.pop_front();
			m_TimeCounter = 0;
		}
		
		break;

	case AP_ChooseMovePos:
		
		m_MovePosUnion = s_RangeHoney->GetMoveRangePath(s_FocusNPC->GetMatrixPosX()+1,s_FocusNPC->GetMatrixPosY());
		m_Proc.pop_front();
		break;

	case AP_MoveCharacter:
		{
			if (m_MoveCharacter == NULL)
			{
				m_MoveCharacter = new cMoveCharacter(s_InfoUnion,s_FocusNPC,m_MovePosUnion,
					s_SelectedPlayer->GetMatrixPosX()+1,s_SelectedPlayer->GetMatrixPosY());
			}
			this->s_InputDevice->Read();

			BOOL msg = m_MoveCharacter->Execute(
				s_InputDevice->GetKeyboardStates(),s_InputDevice->GetKeyboardLocks());

			if (msg == MY_CHARACTER_MOVING_DONE)
			{
				s_FocusNPC->SetMatrixPosX(m_MoveCharacter->GetAimMatrixX());
				s_FocusNPC->SetMatrixPosY(m_MoveCharacter->GetAimMatrixY());
				delete m_MoveCharacter;
				m_MoveCharacter = NULL;
				m_Proc.pop_front();
			}
		}
		break;

	case AP_AttackPrepare:

		s_FightScene->ReloadFightProc();
		s_FightScene->SetAttacker(s_FocusNPC);
		s_FightScene->SetDefender(s_SelectedPlayer);
		s_FightScene->SetIfShow(true);

		m_Proc.pop_front();
		break;

	case AP_Attack:
		{
			this->s_InputDevice->Read();
			int msg = s_FightScene->Execute(
				s_InputDevice->GetKeyboardStates(),s_InputDevice->GetKeyboardLocks());

			if (msg == MY_FIGHT_SCENE_EXIT)
			{
				s_FightScene->SetIfShow(false);
				m_Proc.pop_front();
			}
		}
		break;

	default:
		break;
	}

	return AI_NOT_DONE;
}

list<cCharMovePosUnit> cAIMoveAndAtk::CountCharMoveUnion( cMyCharacter *character,int aimx,int aimy )
{
	list<cCharMovePosUnit> PosUnion;
	int ProcX = character->GetMatrixPosX();
	int ProcY = character->GetMatrixPosY();
	int AimX = aimx;
	int AimY = aimy;

	while ( ProcX!=AimX )
	{
		if ( ProcX>AimX )
		{
			ProcX --;
		}
		else
		{
			ProcX ++;
		}
		PosUnion.push_back( 
			cCharMovePosUnit(ProcX*s_InfoUnion->MatrixUnitWidth,ProcY*s_InfoUnion->MatrixUnitHeight)
			);
	}

	while ( ProcY!=AimY )
	{
		if ( ProcY>AimY )
		{
			ProcY --;
		}
		else
		{
			ProcY ++;
		}
		PosUnion.push_back( 
			cCharMovePosUnit(ProcX*s_InfoUnion->MatrixUnitWidth,ProcY*s_InfoUnion->MatrixUnitHeight)
			);
	}

	return PosUnion;
}

void cAIMoveAndAtk::InitProc()
{
	m_Proc.clear();

	this->m_Proc.push_back(AP_SelectEnemy);
	this->m_Proc.push_back(AP_CountMoveRange);
	this->m_Proc.push_back(AP_ShowMoveRange);
	this->m_Proc.push_back(AP_WaitTwoSec);
	this->m_Proc.push_back(AP_HideMoveRange);
	this->m_Proc.push_back(AP_ChooseMovePos);
	this->m_Proc.push_back(AP_MoveCharacter);
	this->m_Proc.push_back(AP_AttackPrepare);
	this->m_Proc.push_back(AP_Attack);

	s_FocusNPC = NULL;
	s_Players = NULL;
}